package tr.edu.ege.seagent.hobnobontology.schema;

import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.ResourceFactory;
import com.hp.hpl.jena.vocabulary.RDF;
import com.hp.hpl.jena.vocabulary.RDFS;
import com.hp.hpl.jena.vocabulary.XSD;

public class HobNobSchemaCreator {

	private Model schemaModel;

	/**
	 * @return
	 */
	public Model createSchema() {
		schemaModel = ModelFactory.createDefaultModel();

		// LOCATION
		Resource location = createClass(HobNobVocabulary.LOCATION_URI);
		createProperty(HobNobVocabulary.X_COORDINATE, location, XSD.xfloat);
		createProperty(HobNobVocabulary.Y_COORDINATE, location, XSD.xfloat);
		createProperty(HobNobVocabulary.LOCATION_HAS_DBPEDIA_URI, location,
				ResourceFactory.createResource(HobNobVocabulary.PLACE_DBPEDIA_URI));

		// ACTIVITY
		Resource activity = createClass(HobNobVocabulary.ACTIVITY_URI);
		createProperty(HobNobVocabulary.ACTIVITY_NAME, activity, XSD.xstring);
		createProperty(HobNobVocabulary.ACTIVITY_AT_LOCATION_URI, activity,
				location);

		// MEMBER
		Resource member = createClass(HobNobVocabulary.MEMBER_URI);
		createProperty(HobNobVocabulary.NAME_URI, member, XSD.xstring);
		createProperty(HobNobVocabulary.SURNAME_URI, member, XSD.xstring);
		createProperty(HobNobVocabulary.E_MAIL_URI, member, XSD.xstring);
		createProperty(HobNobVocabulary.PHONE_NUMBER_URI, member, XSD.xstring);
		createProperty(HobNobVocabulary.LANGUAGE_URI, member, XSD.language);
		createProperty(HobNobVocabulary.FRIEND_URI, member, member);
		createProperty(HobNobVocabulary.MEMBER_JOIN_ACTIVITY_URI, member,
				activity);

		// MALE
		createClass(HobNobVocabulary.MALE_URI, member);

		// FEMALE
		createClass(HobNobVocabulary.FEMALE_URI, member);

		// NOTIFICATION
		Resource notification = createClass(HobNobVocabulary.NOTIFICATION_URI);
		createProperty(HobNobVocabulary.NOTIFICATION_MESSAGE_URI, notification,
				XSD.xstring);

		createProperty(HobNobVocabulary.NOTIFICATION_HAS_MEMBER_URI,
				notification, member);
		createProperty(HobNobVocabulary.NOTIFICATION_AT_LOCATION_URI,
				notification, location);

		return schemaModel;
	}

	/**
	 * Creates an RDFS class with given URI. It also adds sub-class statements
	 * for the given super classes.
	 * 
	 * @param classURI
	 *            URI of the new class.
	 * @param superClasses
	 *            array of super classes. If the class has no super class, this
	 *            parameter can be ignored.
	 * @return
	 */
	private Resource createClass(String classURI, Resource... superClasses) {
		Resource classResource = schemaModel.createResource(classURI,
				RDFS.Class);
		for (Resource superClass : superClasses) {
			classResource.addProperty(RDFS.subClassOf, superClass);
		}
		return classResource;
	}

	/**
	 * Creates a property with given URI, range, and domain.
	 * 
	 * @param propertyURI
	 *            URI of the created property.
	 * @param domain
	 *            domain of the created property.
	 * @param range
	 *            range of the created property.
	 * @return
	 */
	private Property createProperty(String propertyURI, Resource domain,
			Resource range) {
		// create property...
		Property newProperty = schemaModel.createProperty(propertyURI);
		// type of property
		newProperty.addProperty(RDF.type, RDF.Property);
		// property domain-range
		newProperty.addProperty(RDFS.domain, domain);
		newProperty.addProperty(RDFS.range, range);
		return newProperty;
	}

}